package com.sgcc.pda.greendao.dao;

import android.content.Context;

import com.sgcc.pda.greendao.entity.DaoSession;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.Property;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.query.QueryBuilder;

import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 数据库操作基类.
 *
 * @author 王沛栋
 * @data 2017/12/26 10:43
 */

public class BaseDao<T> {
    public DBManager mDBManager;
    public DaoSession mDaoSession;

    public BaseDao(Context context) {
        mDBManager = DBManager.getInstance();
        mDaoSession = mDBManager.getDaoSession();
        entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }


    /**
     * 获取数据库对象
     *
     * @return
     */
    public Database getCursor() {
        return mDaoSession.getDatabase();
    }


    /**
     * 保存或更新对象
     */
    public boolean insertObject(final T object) {
        boolean flag = false;
        if (null == object) {
            return false;
        }
        try {
            mDaoSession.runInTx(new Runnable() {
                @Override
                public void run() {
                    mDaoSession.insertOrReplace(object);
                }
            });

            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 保存单个实体
     *
     * @param object
     * @param c
     * @return
     */
    public boolean saveObject(final T object, final Class c) {
        boolean flag = false;
        if (null == object) {
            return false;
        }
        try {
            mDaoSession.runInTx(new Runnable() {
                @Override
                public void run() {
                    mDaoSession.getDao(c).saveInTx(object);
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 批量更新多个数据
     *
     * @param objects
     * @param c
     * @return
     */
    public boolean saveMultObject(final List<T> objects, final Class c) {
        boolean flag = false;
        if (null == objects || objects.isEmpty()) {
            return false;
        }
        try {
            mDaoSession.runInTx(new Runnable() {
                @Override
                public void run() {
                    mDaoSession.getDao(c).saveInTx(objects);
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 批量更新多个数据
     *
     * @param objects
     * @param c
     * @return
     */
    public boolean insertMultObject(final List<T> objects, final Class c) {
        boolean flag = false;
        if (null == objects || objects.isEmpty()) {
            return false;
        }
        try {
            mDaoSession.runInTx(new Runnable() {
                @Override
                public void run() {
                    mDaoSession.getDao(c).insertOrReplaceInTx(objects);
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    /**
     * 更新对象
     *
     * @param object
     * @return
     */
    public boolean updateObject(T object) {
        boolean flag = false;
        if (null == object) {
            return false;
        }
        try {
            mDaoSession.update(object);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 批量更新多个数据
     *
     * @param objects
     * @param c
     * @return
     */
    public boolean updateMultObject(final List<T> objects, Class c) {
        boolean flag = false;
        if (null == objects || objects.isEmpty()) {
            return false;
        }
        try {
            mDaoSession.getDao(c).updateInTx(new Runnable() {
                @Override
                public void run() {
                    for (T oject : objects) {
                        mDaoSession.update(oject);
                    }
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除某个数据表
     *
     * @param c
     * @return
     */
    public boolean deleteAll(Class c) {
        boolean flag = false;
        try {
            mDaoSession.deleteAll(c);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除对象
     *
     * @param object
     * @return
     */
    public boolean deleteObject(T object) {
        if (null == object) {
            return false;
        }
        try {
            mDaoSession.delete(object);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 异步批量删除数据
     *
     * @param objects
     * @return
     */
    public boolean deleteMultObject(final List<T> objects, Class c) {
        boolean flag = false;
        if (null == objects || objects.isEmpty()) {
            return false;
        }
        try {
            mDaoSession.getDao(c).deleteInTx(new Runnable() {
                @Override
                public void run() {
                    for (T object : objects) {
                        mDaoSession.delete(object);
                    }
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 获取某个表名
     *
     * @param c
     * @return
     */
    public String getTableName(Class c) {
        return mDaoSession.getDao(c).getTablename();
    }


    /**
     * 根据主键ID来查询
     *
     * @param id
     * @param c
     * @return
     */
    public T queryById(long id, Class c) {
        return (T) mDaoSession.getDao(c).loadByRowId(id);
    }

    /**
     * 根据查询条件查询数据集合
     *
     * @param c
     * @param where
     * @param params
     * @return
     */
    public List<T> queryObject(Class c, String where, String... params) {
        Object obj;
        List<T> objects = null;
        try {
            obj = mDaoSession.getDao(c);
            if (null == obj) return null;
            objects = mDaoSession.getDao(c).queryRaw(where, params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objects;
    }


    /**
     * 查询所有对象
     *
     * @param c
     * @return
     */
    public List<T> queryAll(Class c) {
        List<T> objects = null;
        try {
            objects = (List<T>) mDaoSession.getDao(c).loadAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objects;
    }


    /**
     * 泛型
     */
    public Class<T> entityClass;

    public T queryObject1(Property[] wheres, String[] params) {
        return queryObject1(entityClass, wheres, params);
    }

    /**
     * 根据查询条件查询数据集合
     *
     * @param c      对象
     * @param where  where
     * @param params 参数
     * @return 结果
     */
    public T queryObject1(Class c, Property where, String params) {
        List<T> objects = null;
        try {
            objects = queryObject(c, where, params);
            if (null != objects) {
                return objects.get(0);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据查询条件查询数据集合
     *
     * @param c      对象
     * @param where  条件
     * @param params 参数
     * @return 结果
     */
    public List<T> queryObject(Class c, Property where, String params) {
        Object obj;
        List<T> objects = null;
        try {
            AbstractDao dao = mDaoSession.getDao(c);
            if (null == dao) {
                return null;
            }
            QueryBuilder queryBuilder = dao.queryBuilder();
            queryBuilder.where(where.eq(params));
            objects = queryBuilder.list();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objects;
    }

    /**
     * 根据查询条件查询数据集合
     *
     * @param c      对象
     * @param wheres 条件
     * @param params 参数
     * @return 结果
     */
    public T queryObject1(Class c, Property[] wheres, String[] params) {
        List<T> objects = null;
        try {
            objects = queryObject(c, wheres, params);
            if (null != objects) {
                return objects.get(0);
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据查询条件查询数据集合
     *
     * @param c      对象
     * @param wheres 条件
     * @param params 参数
     * @return 结果
     */
    public List<T> queryObject(Class c, Property[] wheres, String[] params) {
        List<T> objects = null;
        try {
            mDBManager = DBManager.getInstance();
            mDaoSession = mDBManager.getDaoSession();
            AbstractDao dao = mDaoSession.getDao(c);
            if (null == dao) {
                return null;
            }
            QueryBuilder queryBuilder = dao.queryBuilder();
            for (int i = 0; i < wheres.length; i++) {
                queryBuilder.where(wheres[i].eq(params[i]));
            }
            objects = queryBuilder.list();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return objects;
    }

}




